package com.cnap.controller;

import com.cnap.model.cloud.scaling.UpdateScalingParam;
import com.cnap.model.common.CommonResult;
import com.cnap.model.indicator.IndicatorVO;
import com.cnap.model.indicator.UpdateCaseParam;
import com.cnap.model.intelligent.NotifyClusterInfoDTO;
import com.cnap.model.schedule.UpdateMicroServiceStatusParam;
import com.cnap.model.schedule.UpdateMicroserviceClusterParam;
import com.cnap.model.stage.UpdateStageParam;
import com.cnap.service.DistributeDeployService;
import com.cnap.service.IndicatorService;
import com.cnap.service.MicroSvcService;
import com.cnap.service.StrategyService;
import com.cnap.utils.JsonUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 系统级控制类
 *
 * @author xc
 **/
@RestController
@RequestMapping("/sys")
@Api(tags = "系统接口")
public class SystemController {
    /*
    内部接口
    供其余系统调用
    不需要token校验
    查询指标
    更新微服务状态
    更新部署集群信息
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(SystemController.class);

    private final MicroSvcService microSvcService;
    private final IndicatorService indicatorService;
    private final DistributeDeployService distributeDeployService;
    private final StrategyService strategyService;

    @Autowired
    public SystemController(MicroSvcService microSvcService, IndicatorService indicatorService,
                            DistributeDeployService distributeDeployService, StrategyService strategyService) {
        this.microSvcService = microSvcService;
        this.indicatorService = indicatorService;
        this.distributeDeployService = distributeDeployService;
        this.strategyService = strategyService;
    }

    /**
     * 更新微服务状态
     *
     * @param param 更新参数
     * @return 结果
     */
    @PostMapping("/micro-service/status")
    @ApiOperation(value = "更新微服务状态", notes = "更新微服务状态", httpMethod = "POST")
    public CommonResult<String> updateMicroServiceStatus(@Validated @RequestBody UpdateMicroServiceStatusParam param) {
        LOGGER.info("[system]: update microservice status: {}", param);
        boolean result = microSvcService.updateMicroServiceStatus(param);
        return result ? CommonResult.success("success") : CommonResult.failed("fail");
    }

    /**
     * 根据微服务id返回指标（返回微服务所属的应用指标）
     *
     * @param serviceId 微服务id
     * @return 结果
     */
    @GetMapping("/indicator/{serviceId}")
    @ApiOperation(value = "根据服务id查询指标", notes = "根据服务id查询指标", httpMethod = "GET")
    public CommonResult<IndicatorVO> getIndicatorByServiceId(@PathVariable("serviceId") String serviceId) {
        IndicatorVO indicatorVO = indicatorService.getAllIndicatorByServiceId(serviceId);
        return CommonResult.success(indicatorVO);
    }

    /**
     * 根据微服务id更新部署集群信息
     *
     * @param param 参数
     * @return 结果
     */
    @PostMapping("/micro-service/cluster-info")
    @ApiOperation(value = "更新集群信息", notes = "更新集群信息", httpMethod = "POST")
    public CommonResult<String> updateClusterInfo(@RequestBody UpdateMicroserviceClusterParam param) {
        LOGGER.info("update cluster info: {}", param);
        microSvcService.updateClusterInfo(param);
        return CommonResult.success("success");
    }

    /**
     * 更新阶段状态信息
     *
     * @return 结果
     */
    @PostMapping("/stage/update")
    public CommonResult<String> updateStageStatus(@RequestBody @Validated UpdateStageParam updateStageParam) {
        LOGGER.info("update stage, {}", updateStageParam);
        boolean result = distributeDeployService.updateStage(updateStageParam);
        return result ? CommonResult.success("success") : CommonResult.failed("fail");
    }

    /**
     * 更新策略信息
     *
     * @param updateScalingParam 参数
     * @return 结果
     */
    @PostMapping("/strategy/update")
    public CommonResult<String> updateVmScalingPolicy(@RequestBody @Validated UpdateScalingParam updateScalingParam) {
        LOGGER.info("update scaling policy: {}", JsonUtil.objectToJsonStr(updateScalingParam));
        microSvcService.updateScalingPolicy(updateScalingParam);
        return CommonResult.success("success");
    }

    /**
     * 更新指标实例
     *
     * @param updateCaseParam 参数
     * @return 结果
     */
    @PostMapping("/case/update")
    public CommonResult<String> updateIndicatorCase(@RequestBody UpdateCaseParam updateCaseParam) {
        LOGGER.info("[indicator]: update case by param: {}", JsonUtil.objectToJsonStr(updateCaseParam));
        boolean result = indicatorService.updateCaseValue(updateCaseParam);
        return result ? CommonResult.success("success") : CommonResult.failed("failed");
    }

    /**
     * 迁移时发送给集群控制台的创建虚机请求，需要回调此接口，告诉应用管理创建的集群名称
     *
     * @param notifyClusterInfoDTO 参数
     * @return 结果
     */
    @PostMapping("/intelligent/update/cluster")
    public CommonResult<String> notifyClusterInfoDueTOMigrate(@RequestBody NotifyClusterInfoDTO notifyClusterInfoDTO) {
        strategyService.notifyClusterInfoByMigrateCreateResource(notifyClusterInfoDTO);
        return CommonResult.success("success");
    }
}
